// StateSyncException.java
package org.zjx.exception;

import lombok.Getter;
import java.util.Optional;

/**
 * 状态同步异常 - 当游戏状态同步过程中出现问题时抛出
 *
 * 这个异常表示在客户端和服务器之间同步游戏状态时发生错误，
 * 如版本不匹配、并发修改等。
 */
@Getter
public class StateSyncException extends RuntimeException {
    // 错误代码，用于分类不同类型的同步错误
    private final String errorCode;
    // 涉及的客户端ID(如果有)
    private final String clientId;

    /**
     * 使用错误代码和消息构造异常
     *
     * @param errorCode 预定义的错误代码
     * @param message 描述同步错误的详细信息
     */
    public StateSyncException(String errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
        this.clientId = null;
    }

    /**
     * 使用错误代码、客户端ID和消息构造异常
     *
     * @param errorCode 预定义的错误代码
     * @param clientId 涉及的客户端ID
     * @param message 描述同步错误的详细信息
     */
    public StateSyncException(String errorCode, String clientId, String message) {
        super(message);
        this.errorCode = errorCode;
        this.clientId = clientId;
    }

    /**
     * 使用错误代码、客户端ID、消息和原因构造异常
     *
     * @param errorCode 预定义的错误代码
     * @param clientId 涉及的客户端ID
     * @param message 描述同步错误的详细信息
     * @param cause 导致此异常的根本原因
     */
    public StateSyncException(String errorCode, String clientId, String message, Throwable cause) {
        super(message, cause);
        this.errorCode = errorCode;
        this.clientId = clientId;
    }

    // 预定义错误码 - 用于分类不同类型的同步错误
    public static final String VERSION_MISMATCH = "SYNC_001";          // 版本不匹配
    public static final String CONCURRENT_MODIFICATION = "SYNC_002";   // 并发修改
    public static final String SERIALIZATION_ERROR = "SYNC_003";       // 序列化错误
    public static final String PROTOCOL_VIOLATION = "SYNC_004";        // 协议违反

    /**
     * 获取客户端ID(可能为null)
     *
     * @return 涉及的客户端ID的Optional包装
     */
    public Optional<String> getClientId() {
        return Optional.ofNullable(clientId);
    }

    /**
     * 工具方法 - 创建版本不匹配异常
     *
     * @param expected 期望的版本号
     * @param actual 实际的版本号
     * @return 配置好的StateSyncException实例
     */
    public static StateSyncException versionMismatch(long expected, long actual) {
        return new StateSyncException(
                VERSION_MISMATCH,
                String.format("Version conflict. Expected:%d Actual:%d", expected, actual)
        );
    }
}